import numpy as np
import numpy.linalg as nm  
from math import sqrt

def secure_parameters(X,Y):
    X=np.asarray(X)
    Y=np.asarray(Y)
    X.shape=X.size
    Y.shape=Y.size
    return (X,Y)



def householder_matrix (X,Y):
    n=X.size
    (X,Y)=secure_parameters(X,Y)
    epsilon=1e-10
    bool=1
    I=np.eye(X.size,X.size)
    norme=(nm.norm(X))-(nm.norm(Y))
    if (((norme>epsilon) or (norme<-epsilon)) or (X.size != Y.size )):  
        print "Incompatible arguments"
        bool=0
        return (X,I,bool)
    elif (all(X==Y)):  
        return (X,I,bool)
         
    else:
        
        U=(1/nm.norm(X-Y))*(X-Y)
        N=U
        N.shape=(N.size,1)
        return (U,I-2*np.dot(N,np.transpose(N)),bool) 
        



def householder_product_vector(U,X):
    n=X.size
    (U,X)=secure_parameters(U,X)
    scalar=np.inner(U,X)
    return X-2*scalar*U
    
def householder_product_matrix(U,M):
    n=U.size
    
    result = np.zeros([n,n])
    
    for i in range(n):
        X= householder_product_vector(U,M[:,i])
        X.shape=(X.size)
        result[:,i]=X
        
        
        
    return result


print "                 Test sur la partie 1 : \n"
print "Question 1 :"
print "Exemple du sujet :"
print "Matrice X :"
X=np.array([[3],[4],[0]])
print X
print "A envoyer sur :"
Y=np.array([[0],[0],[5]])
print Y
print "grace a la matrice de Householder suivante :"
print householder_matrix(X,Y)[1]

print "\nQuestion 2 :"
(U,M,bool)=householder_matrix(X,Y)
print "Matrice U :"
print U
print "vecteur X :"
print X
print "produit de Householder de U par X :"
print householder_product_vector(U,X)
print "produit de matrices de python:"
print np.dot(M,X)
print "\n"
print "Matrice N :"
N=np.matrix([
    [4,5,6],[3,2,4],[4,4,7]])
print N
print "Matrice U :"
print U
print "produit de Householder de U par N"
print householder_product_matrix(U,N)
print "produit de matrices de python"
print M*N
print "\n"


